home *** CD-ROM | disk | FTP | other *** search
- #include <math.h>
- #include <stdio.h>
- #include <vogle.h>
- #include "art.h"
- #include "macro.h"
- #include "gram.h"
-
- extern int lookatdone;
- extern int longlines;
- extern mats *mstackp;
- extern hlist *fhlist;
- extern float tolerance;
-
- /*
- * coneinit
- *
- * initialise the function pointers and fields for a cone object,
- * returning its pointer.
- */
- void
- coneinit(o, d)
- object *o;
- details *d;
- {
- int first, faces;
- vector base, tip, basescale, tipscale, tmp;
- details *ld;
- float grad;
- float apex_x, apex_y, apex_z, apex_r;
- float base_x, base_y, base_z, base_r;
- float len0, len1, len_x, len_y, len_z;
- float cosine, sine, dx1, dy1, dx2, dy2, delta;
- float cx1, cy1, cx2, cy2;
- int i;
- Matrix m;
-
- if (!lookatdone)
- deflookat();
-
- faces = 0;
- first = 1;
-
- base.x = base.y = base.z = 0.0;
- tip.x = tip.y = tip.z = 1.0;
-
- basescale.x = basescale.y = 1.0;
- tipscale.x = tipscale.y = 0.0;
-
- while (d != (details *)NULL) {
- switch (d->type) {
- case VERTEX:
- tip = d->u.v;
- break;
- case CENTER:
- if (faces == 0)
- base = d->u.v;
- else
- tip = d->u.v;
- faces++;
- break;
- case RADIUS:
- if (first) {
- basescale.x = basescale.y = d->u.f;
- first = 0;
- } else
- tipscale.x = tipscale.y = d->u.f;
- break;
- case RADII:
- if (first) {
- tipscale.x = d->u.v.x;
- tipscale.y = d->u.v.y;
- first = 0;
- } else {
- basescale.x = d->u.v.x;
- basescale.y = d->u.v.y;
- }
- break;
- default:
- warning("art: illegal field in cone ignored.\n");
- }
- ld = d;
- d = d->nxt;
- free(ld);
- }
-
- /* this axis is done in obj_transform */
- basescale.z = tipscale.z = 1.0;
-
- if (faces == 2) {
- if (tipscale.x > basescale.x) {
- tmp = tip;
- tip = base;
- base = tmp;
- tmp = tipscale;
- tipscale = basescale;
- basescale = tmp;
- }
- o->obj.cne_tipval = tipscale.x / basescale.x;
- grad = (tip.x - base.x) / (basescale.x - tipscale.x);
- tip.x += grad * tipscale.x;
- grad = (tip.y - base.y) / (basescale.x - tipscale.x);
- tip.y += grad * tipscale.x;
- grad = (tip.z - base.z) / (basescale.x - tipscale.x);
- tip.z += grad * tipscale.x;
- } else
- o->obj.cne_tipval = 0.0;
-
- tmp.x = (tip.x + base.x) / 2.0;
- tmp.y = (tip.y + base.y) / 2.0;
- tmp.z = (tip.z + base.z) / 2.0;
-
- len_x = tip.x - base.x;
- len_y = tip.y - base.y;
- len_z = tip.z - base.z;
-
- len0 = sqrt(len_x * len_x + len_y * len_y + len_z * len_z);
-
- len1 = sqrt(len_x * len_x + len_z * len_z);
-
- /*
- * Draw the axis center line in YELLOW
- */
- color(YELLOW);
- move(tip.x, tip.y, tip.z);
- draw(base.x, base.y, base.z);
-
- /*
- * And the rest in GREEN...
- */
- color(GREEN);
-
- pushmatrix();
-
- calctransforms(mstackp);
- multmatrix(mstackp->obj2ray);
-
- translate(base.x, base.y, base.z);
-
- identmatrix(m);
-
- if (len1 == 0.0) {
- cosine = 0.0;
- sine = 1.0;
- } else {
- cosine = len_z / len1;
- sine = len_x / len1;
- }
-
- /* rotate about y */
- m[0][0] = cosine;
- m[0][2] = -sine;
- m[2][0] = sine;
- m[2][2] = cosine;
- multmatrix(m);
-
- identmatrix(m);
-
- if (len0 == 0.0) {
- cosine = 0.0;
- sine = 1.0;
- } else {
- cosine = len1 / len0;
- sine = -len_y / len0;
- }
-
- /* rotate about x */
- m[1][1] = cosine;
- m[1][2] = sine;
- m[2][1] = -sine;
- m[2][2] = cosine;
- multmatrix(m);
-
- /*
- * Draw the end circles...
- */
- pushmatrix();
- scale(basescale.x, basescale.y, 1.0);
-
- circle (0.0, 0.0, 1.0);
-
- pushmatrix();
- scale(tipscale.x, tipscale.y, 1.0);
- translate(0.0, 0.0, len0);
- circle (0.0, 0.0, 1.0);
- popmatrix();
- popmatrix();
-
-
-
- /*
- * Draw the logitudinal lines...
- */
- delta = 2 * PI / longlines;
-
- cosine = cos(delta);
- sine = sin(delta);
-
- cx1 = basescale.x;
- cy1 = 0.0;
- cx2 = tipscale.x;
- cy2 = 0.0;
-
- move(cx1, cy1, 0.0);
- draw(cx2, cy2, len0);
-
- for (i = 0; i < longlines; i++) {
- dx1 = cx1;
- dy1 = cy1;
- cx1 = dx1 * cosine - dy1 * sine;
- cy1 = dx1 * sine + dy1 * cosine;
- dx2 = cx2;
- dy2 = cy2;
- cx2 = dx2 * cosine - dy2 * sine;
- cy2 = dx2 * sine + dy2 * cosine;
- move(cx1, cy1, 0.0);
- draw(cx2, cy2, len0);
- }
- popmatrix();
- }
-